package juc.thread.secuity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/*
* 活跃性-死锁
* 定位死锁 jstack | jconsole
* */
public class Test13 {
    private static Object lock1=new Object();
    private static Object lock2=new Object();
    public static void main(String[] args) {
          new Thread(()->{
              synchronized (lock1){
                  System.out.println("获得lock1");
                  System.out.println("等待lock2");
                  try {
                      Thread.sleep(1);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  synchronized (lock2){
                      System.out.println("获得lock2");
                  }
              }
          },"t1").start();
          new Thread(()->{
              synchronized (lock2){
                  System.out.println("获得lock2");
                  System.out.println("等待lock1");
                  synchronized (lock1){
                      System.out.println("获得lock1");
                  }
              }
        },"t2").start();
    }
}
/*测试哲学家就餐问题(死锁)
*多线程以相同的抢锁顺序执行 可以解决死锁问题 但可能会引发(活跃性-饥饿)现象
* */
class test14{
    public static void main(String[] args) throws InterruptedException {
        List<ChopstickReentrantLock>chopsticks=new ArrayList<>(5);
        for (int i = 0; i <5 ; i++) {
            chopsticks.add(new ChopstickReentrantLock(i+1));
        }
//        Chopstick chopstick = new Chopstick(-1);//公筷放中间的一根筷
        new Philosopher("苏格拉底",chopsticks.get(0),chopsticks.get(1)).start();
        Thread.sleep(2000);
        new Philosopher("柏拉图",chopsticks.get(1),chopsticks.get(2)).start();
        new Philosopher("亚里士多德",chopsticks.get(2),chopsticks.get(3)).start();
        new Philosopher("阿基米德",chopsticks.get(3),chopsticks.get(4)).start();
        //让任意相邻俩个人抢筷顺序相反(一个先拿左筷再拿右筷子 一个先拿右筷再拿左筷子 由a->b 和 b->a 变为 a->b a->b)这样可以避免死锁 但会引发饥饿
//        new Philosopher("赫拉克利特",chopsticks.get(0),chopsticks.get(4)).start();
        new Philosopher("赫拉克利特",chopsticks.get(4),chopsticks.get(0)).start();
    }
}
class ChopstickReentrantLock extends ReentrantLock {
    private int ID;

    public ChopstickReentrantLock(int ID) {
        this.ID = ID;
    }

    @Override
    public String toString() {
        return "chopstick{" +
                "ID=" + ID +
                '}';
    }
}
class Chopstick{
      private int ID;

    public Chopstick(int ID) {
        this.ID = ID;
    }

    @Override
    public String toString() {
        return "chopstick{" +
                "ID=" + ID +
                '}';
    }
}
class Philosopher extends Thread{
      private  Chopstick LEFT;
      private Chopstick RIGHT;
      private String NAME;

    private  ChopstickReentrantLock LEFT_R;
    private ChopstickReentrantLock RIGHT_R;
    public Philosopher(String name,ChopstickReentrantLock left,ChopstickReentrantLock right){
        NAME=name;
        LEFT_R=left;
        RIGHT_R=right;
    }
      public Philosopher(String name,Chopstick left,Chopstick right){
            NAME=name;
            LEFT=left;
            RIGHT=right;
      }
    @Override
    public void run() {
        while (true){
            if (LEFT_R.tryLock()) {
                try {
                    System.out.println(NAME+"拿到了l"+LEFT_R);
                    if (RIGHT_R.tryLock()) {
                        try {
                            System.out.println(NAME+"拿到了r"+RIGHT_R);
                            System.out.println(NAME+"开吃...........................");
                            try {
                                Thread.sleep(500);//吃饭时间
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        } finally {
                            RIGHT_R.unlock();
                        }
                    }
                } finally {
                    LEFT_R.unlock();
                }
            }
            System.out.println(NAME+"thinking....");
            try {
                Thread.sleep(200);//思考时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    /*     while (true){
             synchronized (LEFT){
//                 System.out.println(NAME+"拿到了l"+LEFT);
                 synchronized (RIGHT){
//                     System.out.println(NAME+"拿到了r"+RIGHT);
                     System.out.println(NAME+"开吃...");
                     try {
                         Thread.sleep(200);//吃饭时间
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }*/
//             System.out.println("放下"+LEFT+"和"+RIGHT+"开始思考...");
//             try {
//                 Thread.sleep(3000);
//             } catch (InterruptedException e) {
//                 e.printStackTrace();
//             }
//             }
    }
}
